SQLite数据库与Contentprovider(2)
在创建ContentProvider时,需要首先使用数据库、文件系统或网络实现底层存储功能,
然后在继承ContentProvider的类中实现基本数据操作的接口函数,包括添加、删除、查找和更新等功能。
调用者不能够直接调用ContentProvider的接口函数,而需要使用ContentResolver对象,
通过URI间接调用ContentProvider。下图是ContentProvider调用关系。

URI:
URI是通用资源标志符(Uniform Resource Identifier),用来定位任何远程或本地的可用资源
ContentProvider使用的URI语法结构如下
content://<authority>/<data_path>/<id>content://是通用前缀,表示该URI用于ContentProvider定位资源,无需修改。
<authority>是授权者名称,用来确定具体由哪一个ContentProvider提供资源。因此,一般<authority>都由类的小写全称组成,以保证唯一性。
<data_path>是数据路径,用来确定请求的是哪个数据集。
例如:
content://edu.hrbeu.peopleprovider/people/3可以省略id(/3)部分那么意味着整个数据。
UriMatcher:
在新构造的ContentProvider类中,通过构造一个UriMatcher,判断URI是单条数据还是多条数据。
public void addURI (String authority, String path, int code)
authority表示匹配的授权者名称
path表示数据路径
#可以代表任何数字 (content://<authority>/<data_path>/#)
code表示返回代码(uriMatcher.match(uri))的返回值)
注册ContentProvider :
<provider android:name = '.PeopleProvider' android:authorities = 'edu.hrbeu.peopleprovider'/>实例:
ContentProvider一般用于两个不同的进程之间的数据共享。
假设我们有一个新的工程(app),在此工程中创建一个people.db数据库,然后通过自定义了一个ContentProvider来共享数据库中的data。 我们可以通过注册provider时用到的authority在配合db path之类的来连接(content://<authority>/<data_path>/#)读取内容提供者(不同进程)的数据。首先是步骤1:
*只要在AndroidManifast中注册provider就会执行对应的provider类。无需再MainActivity中调用或无需直接调用自定义的new provider。
即系统自动会加载调用PeopleProvider类。
<provider android:name = '.PeopleProvider' android:authorities = 'edu.hrbeu.peopleprovider'/>继承ContentProvider时代码如下:
import android.content.*; import android.database.Cursor; import android.net.Uri; public class PeopleProvider extends ContentProvider{ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub return null; } @Override public boolean onCreate() { // TODO Auto-generated method stub return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }类似数据库操作。可以这么理解,相对来说好理解。
开始贴代码。。。
package edu.hrbeu.contentproviderdemo; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; public class PeopleProvider extends ContentProvider { private static final String DB_NAME = 'people.db'; private static final String DB_TABLE = 'peopleinfo'; private static final int DB_VERSION = 1; private SQLiteDatabase db; private DBOpenHelper dbOpenHelper; private static final int MULTIPLE_PEOPLE = 1; private static final int SINGLE_PEOPLE = 2; private static final UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(People.AUTHORITY, People.PATH_MULTIPLE, MULTIPLE_PEOPLE); uriMatcher.addURI(People.AUTHORITY, People.PATH_SINGLE, SINGLE_PEOPLE); } @Override public boolean onCreate() { // TODO Auto-generated method stub Context context = getContext(); dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION); db = dbOpenHelper.getWritableDatabase(); if (db == null) return false; else return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(DB_TABLE); switch(uriMatcher.match(uri)){ case SINGLE_PEOPLE: qb.appendWhere(People.KEY_ID + '=' + uri.getPathSegments().get(1)); break; default: break; } Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub switch(uriMatcher.match(uri)){ case MULTIPLE_PEOPLE: return People.MINE_TYPE_MULTIPLE; case SINGLE_PEOPLE: return People.MINE_TYPE_SINGLE; default: throw new IllegalArgumentException('Unkown uri:'+uri); } } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub long id = db.insert(DB_TABLE, null, values); if ( id > 0 ){ Uri newUri = ContentUris.withAppendedId(People.CONTENT_URI, id); getContext().getContentResolver().notifyChange(newUri, null); return newUri; } throw new SQLException('Failed to insert row into ' + uri); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count = 0; switch(uriMatcher.match(uri)){ case MULTIPLE_PEOPLE: count = db.delete(DB_TABLE, selection, selectionArgs); break; case SINGLE_PEOPLE: String segment = uri.getPathSegments().get(1); count = db.delete(DB_TABLE, People.KEY_ID + '=' + segment, selectionArgs); break; default: throw new IllegalArgumentException('Unsupported URI:' + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count; switch(uriMatcher.match(uri)){ case MULTIPLE_PEOPLE: count = db.update(DB_TABLE, values, selection, selectionArgs); break; case SINGLE_PEOPLE: String segment = uri.getPathSegments().get(1); count = db.update(DB_TABLE, values, People.KEY_ID+'='+segment, selectionArgs); break; default: throw new IllegalArgumentException('Unknow URI:' + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } private static class DBOpenHelper extends SQLiteOpenHelper { public DBOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } private static final String DB_CREATE = 'create table ' + DB_TABLE + ' (' + People.KEY_ID + ' integer primary key autoincrement, ' + People.KEY_NAME+ ' text not null, ' + People.KEY_AGE+ ' integer,' + People.KEY_HEIGHT + ' float);'; @Override public void onCreate(SQLiteDatabase _db) { // TODO Auto-generated method stub _db.execSQL(DB_CREATE); } @Override public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) { // TODO Auto-generated method stub _db.execSQL('DROP TABLE IF EXISTS ' + DB_TABLE); onCreate(_db); } } } package edu.hrbeu.contentproviderdemo; import android.net.Uri; public class People{ public static final String MIME_DIR_PREFIX = 'vnd.android.cursor.dir'; public static final String MIME_ITEM_PREFIX = 'vnd.android.cursor.item'; public static final String MINE_ITEM = 'vnd.hrbeu.people'; public static final String MINE_TYPE_SINGLE = MIME_ITEM_PREFIX + '/' + MINE_ITEM; public static final String MINE_TYPE_MULTIPLE = MIME_DIR_PREFIX + '/' + MINE_ITEM; public static final String AUTHORITY = 'edu.hrbeu.peopleprovider'; public static final String PATH_SINGLE = 'people/#'; public static final String PATH_MULTIPLE = 'people'; public static final String CONTENT_URI_STRING = 'content://' + AUTHORITY + '/' + PATH_MULTIPLE; public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); public static final String KEY_ID = '_id'; public static final String KEY_NAME = 'name'; public static final String KEY_AGE = 'age'; public static final String KEY_HEIGHT = 'height'; }MainActivity是空的。。。不贴出来了。
运行结果没有任何内容,因为仅是添加了一个provider。

看一下步骤2:
在另一个App中调用此ContentProvider。
无需再AndroidManifast中注册provider。
只需对应步骤1中的People类里的静态变量是完全匹配的就是可以了。
也就是说URI需要与我们自定义的ContentProvider保持一致。
package edu.hrbeu.contentresolverdemo; import android.net.Uri; public class People{ public static final String MIME_DIR_PREFIX = 'vnd.android.cursor.dir'; public static final String MIME_ITEM_PREFIX = 'vnd.android.cursor.item'; public static final String MINE_ITEM = 'vnd.hrbeu.people'; public static final String MINE_TYPE_SINGLE = MIME_ITEM_PREFIX + '/' + MINE_ITEM; public static final String MINE_TYPE_MULTIPLE = MIME_DIR_PREFIX + '/' + MINE_ITEM; public static final String AUTHORITY = 'edu.hrbeu.peopleprovider'; public static final String PATH_SINGLE = 'people/#'; public static final String PATH_MULTIPLE = 'people'; public static final String CONTENT_URI_STRING = 'content://' + AUTHORITY + '/' + PATH_MULTIPLE; public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); public static final String KEY_ID = '_id'; public static final String KEY_NAME = 'name'; public static final String KEY_AGE = 'age'; public static final String KEY_HEIGHT = 'height'; }操作Contentpriver提供的数据我们需要用到ContentResolver:
package edu.hrbeu.contentresolverdemo; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class ContentResolverDemo extends Activity { private EditText nameText; private EditText ageText; private EditText heightText; private EditText idEntry; private TextView labelView; private TextView displayView; private ContentResolver resolver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_content_resolver_demo); nameText = (EditText) findViewById(R.id.name); ageText = (EditText) findViewById(R.id.age); heightText = (EditText) findViewById(R.id.hight); idEntry = (EditText) findViewById(R.id.id); labelView = (TextView) findViewById(R.id.label); displayView = (TextView) findViewById(R.id.display); Button addButton = (Button) findViewById(R.id.button1); Button queryAllButton = (Button) findViewById(R.id.button2); Button clearButton = (Button) findViewById(R.id.button3); Button queryButton = (Button) findViewById(R.id.button6); Button deleteButton = (Button) findViewById(R.id.button5); Button updateButton = (Button) findViewById(R.id.button7); resolver = this.getContentResolver(); addButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub ContentValues values = new ContentValues(); values.put(People.KEY_NAME, nameText.getText().toString()); values.put(People.KEY_AGE, Integer.parseInt(ageText.getText().toString())); values.put(People.KEY_HEIGHT, Float.parseFloat(heightText.getText().toString())); Uri newUri = resolver.insert(People.CONTENT_URI, values); labelView.setText('添加成功,URI:' + newUri); } }); queryAllButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Cursor cursor = resolver.query(People.CONTENT_URI, new String[] { People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT }, null, null, null); if (cursor == null) { labelView.setText('数据库中没有数据'); return; } labelView.setText('数据库:' + String.valueOf(cursor.getCount()) + '条记录'); String msg = ''; if (cursor.moveToFirst()) { do { msg += 'ID:' + cursor.getInt(cursor .getColumnIndex(People.KEY_ID)) + ','; msg += '姓名:' + cursor.getString(cursor .getColumnIndex(People.KEY_NAME)) + ','; msg += '年龄:' + cursor.getInt(cursor .getColumnIndex(People.KEY_AGE)) + ', '; msg += '身高:' + cursor.getFloat(cursor .getColumnIndex(People.KEY_HEIGHT)) + ' '; } while (cursor.moveToNext()); } displayView.setText(msg); } }); clearButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub displayView.setText(''); } }); queryButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri.parse(People.CONTENT_URI_STRING + '/' + idEntry.getText().toString()); Cursor cursor = resolver.query(uri, new String[] { People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT }, null, null, null); if (cursor == null) { labelView.setText('数据库中没有数据'); return; } String msg = ''; if (cursor.moveToFirst()) { msg += 'ID:' + cursor.getInt(cursor .getColumnIndex(People.KEY_ID)) + ','; msg += '姓名:' + cursor.getString(cursor .getColumnIndex(People.KEY_NAME)) + ','; msg += '年龄:' + cursor.getInt(cursor .getColumnIndex(People.KEY_AGE)) + ', '; msg += '身高:' + cursor.getFloat(cursor .getColumnIndex(People.KEY_HEIGHT)) + ' '; } labelView.setText('数据库:'); displayView.setText(msg); } }); deleteButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri.parse(People.CONTENT_URI_STRING + '/' + idEntry.getText().toString()); int result = resolver.delete(uri, null, null); String msg = '删除ID为' + idEntry.getText().toString() + '的数据' + (result > 0 ? '成功' : '失败'); labelView.setText(msg); } }); updateButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub ContentValues values = new ContentValues(); values.put(People.KEY_NAME, nameText.getText().toString()); values.put(People.KEY_AGE, Integer.parseInt(ageText.getText().toString())); values.put(People.KEY_HEIGHT, Float.parseFloat(heightText.getText().toString())); Uri uri = Uri.parse(People.CONTENT_URI_STRING + '/' + idEntry.getText().toString()); int result = resolver.update(uri, values, null, null); String msg = '更新ID为' + idEntry.getText().toString() + '的数据' + (result > 0 ? '成功' : '失败'); labelView.setText(msg); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.content_resolver_demo, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }事成相识的布局文件也附上:
<RelativeLayout xmlns:android='' xmlns:tools='' android:layout_width='match_parent' android:layout_height='match_parent' android:paddingBottom='@dimen/activity_vertical_margin' android:paddingLeft='@dimen/activity_horizontal_margin' android:paddingRight='@dimen/activity_horizontal_margin' android:paddingTop='@dimen/activity_vertical_margin' tools:context='edu.hrbeu.contentresolverdemo.ContentResolverDemo' > <TextView android:id='@+id/Username' android:layout_height='wrap_content' android:layout_width='fill_parent' android:text='用户名:'> </TextView> <EditText android:id='@+id/name' android:layout_width='fill_parent' android:layout_height='wrap_content' android:layout_below='@id/Username' > </EditText> <TextView android:id='@+id/Userage' android:layout_height='wrap_content' android:layout_width='fill_parent' android:layout_below='@id/name' android:text='年龄:'> </TextView> <EditText android:id='@+id/age' android:layout_height='wrap_content' android:layout_width='fill_parent' android:layout_below='@id/Userage'> </EditText> <TextView android:id='@+id/Userhight' android:layout_height='wrap_content' android:layout_width='fill_parent' android:layout_below='@id/age' android:text='身高:'> </TextView> <EditText android:id='@+id/hight' android:layout_height='wrap_content' android:layout_width='fill_parent' android:layout_below='@id/Userhight'> </EditText> <Button android:id='@+id/button2' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_alignBaseline='@+id/button1' android:layout_alignBottom='@+id/button1' android:layout_centerHorizontal='true' android:text='全部显示' /> <Button android:id='@+id/button3' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_alignBaseline='@+id/button2' android:layout_alignBottom='@+id/button2' android:layout_alignRight='@+id/hight' android:text='清除显示' /> <TextView android:id='@+id/Userid' android:layout_height='wrap_content' android:layout_width='fill_parent' android:layout_below='@id/button1' android:text='ID:'> </TextView> <EditText android:id='@+id/id' android:layout_height='wrap_content' android:layout_width='fill_parent' android:layout_below='@id/Userid'> </EditText> <Button android:id='@+id/button6' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_alignBaseline='@+id/button5' android:layout_alignBottom='@+id/button5' android:layout_alignLeft='@+id/button2' android:text='ID查询' /> <Button android:id='@+id/button7' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_alignBaseline='@+id/button6' android:layout_alignBottom='@+id/button6' android:layout_alignLeft='@+id/button3' android:text='ID更新' /> <Button android:id='@+id/button1' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_below='@+id/hight' android:text='添加数据' /> <Button android:id='@+id/button5' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_alignLeft='@+id/id' android:layout_below='@+id/id' android:text='ID删除' /> <TextView android:id='@+id/display' android:layout_width='fill_parent' android:layout_height='wrap_content' android:layout_alignLeft='@+id/label' android:layout_below='@+id/label' android:layout_marginTop='23dp' /> <TextView android:id='@+id/label' android:layout_width='fill_parent' android:layout_height='wrap_content' android:layout_alignLeft='@+id/button5' android:layout_below='@+id/button6' android:layout_marginTop='14dp' /> </RelativeLayout>运行结果:

相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/sql/sqlite/10585.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
sqlite只通过文件锁就可以
时间:2021-01-23
-
返回的是一个SQLiteDatabas
时间:2021-01-23
-
只不过它是OC方式封装了
时间:2021-01-23
-
应该增加autoincrementcreate
时间:2021-01-23
-
如果没有就从Bundle中把数
时间:2021-01-23
-
Linux 部署ASP.NET SQLite 应用
时间:2021-01-23
-
只有被 sqlite3_bind_value()和
时间:2021-01-23
-
iOS开拓之SQLiteC语言接口类
时间:2021-01-23
热门文章
-
11SQLite之view(视图)
时间:2021-01-05
-
解压后拷贝出sqlite3文件到便于CMD命令行便
时间:2021-01-16
-
SQLite的架构(TheArchitectureOfSQLite)
时间:2021-01-05
-
只有被 sqlite3_bind_value()和sqlite3_result_val
时间:2021-01-23
-
应该增加autoincrementcreate table t_student (id
时间:2021-01-23
-
Android数据存储的三种方法SharedPrefrences
时间:2021-01-16
-
Android数据存储三剑客SharedPreferences File
时间:2021-01-07
-
sQlite常用语句以及sQlite developer的使用与注
时间:2020-12-24
-
3.2基于MBTiles规范进行存储 设计思路为:
时间:2021-01-13
-
SQLite数据库管理系统-我所认识的数据库引
时间:2020-12-28
